﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;

namespace CXW.Core.Sharp.Sda
{
    /// <summary></summary>
    public sealed class SharpDevelopHost
    {
        internal AppDomain appDomain;
        CallHelper helper;
        /// <summary></summary>
        public SharpDevelopHost()
        {
            this.appDomain = AppDomain.CurrentDomain;
            helper = (CallHelper)appDomain.CreateInstanceAndUnwrap(typeof(SharpDevelopHost).Assembly.FullName, typeof(CallHelper).FullName);
            StartupSettings startup = new StartupSettings()
            {
                ApplicationRootPath = appDomain.BaseDirectory,
                DataDirectory = appDomain.BaseDirectory,
                ConfigDirectory = Path.Combine(appDomain.BaseDirectory, @"Data\Settings")
            };
            startup.AddAddInsFromDirectory(Path.Combine(startup.ApplicationRootPath, "AddIns"));

            helper.InitSharpDevelopCore(new CallbackHelper(this), startup);
        }
        /// <summary></summary>
        public SharpDevelopHost(StartupSettings startup)
        {
            if (startup == null)
            {
                throw new ArgumentNullException("startup");
            }
            this.appDomain = AppDomain.CurrentDomain;
            helper = (CallHelper)appDomain.CreateInstanceAndUnwrap(typeof(SharpDevelopHost).Assembly.FullName, typeof(CallHelper).FullName);
            helper.InitSharpDevelopCore(new CallbackHelper(this), startup);
        }

        /// <summary></summary>
        public void RunWorkbench()
        {
            helper.RunWorkbench();
        }

        #region Callback Events  
        /// <summary>
        /// Event before the workbench starts running.
        /// </summary>
        [SuppressMessage("Microsoft.Naming", "CA1713:EventsShouldNotHaveBeforeOrAfterPrefix")]
        public event EventHandler BeforeRunWorkbench;

        /// <summary>
        /// Event after the workbench has been unloaded.
        /// </summary>
        public event EventHandler WorkbenchClosed;

        internal sealed class CallbackHelper : MarshalByRefObject
        {
            readonly SharpDevelopHost host;

            public CallbackHelper(SharpDevelopHost host)
            {
                this.host = host;
            }

            public override object InitializeLifetimeService()
            {
                return null;
            }

            internal void BeforeRunWorkbench()
            {
                host.BeforeRunWorkbench?.Invoke(host, EventArgs.Empty);
            }

            internal void WorkbenchClosed()
            {
                host.WorkbenchClosed?.Invoke(host, EventArgs.Empty);
            }
        }
        #endregion
    }
}